<template>
	<view class="lSwipeAction">
		<view class="swipe-item" :class="[isShowBtn ? 'swipe-action-show' : '']"
			:style="{ transform: 'translate(' + position.pageX + 'px,0)' }">
			<view class="swipe-content" @touchstart="onTouchstart" @touchmove="onTouchmove" @touchend="onTouchend"
				@mousedown="onTouchstart" @mousemove="onTouchmove" @mouseup="onTouchend">
				<slot></slot>
			</view>
			<view class="swipe-button-right-group" v-if="options.length > 0" @touchend.stop="loop">
				<view class="swipe-button-right-item" v-for="(item, index) in options" :key="index"
					:style="{ backgroundColor: item.background || '#f7f7f7', color: item.color, width: item.width + 'rpx' }"
					:data-index="index" @tap="handlerButton(index)">
					
					<uni-icons type="trash" color="rgba(255, 255, 255, 1)" size="20"></uni-icons>
					<text>{{ item.name }}</text>
				</view>
			</view>
		</view>
		<view v-if="isShowBtn && showMask" class="swipe-action-mask" @tap.stop="closeSwipe"
			@touchstart.stop.prevent="closeSwipe"></view>
	</view>
</template>

<script>
	export default {
		name: 'lSwipeAction',
		props: {
			options: {
				type: Array,
				default () {
					return [];
				}
			},
			//点击按钮时是否自动关闭
			isClickClose: {
				type: Boolean,
				default: false
			},
			//设为false，点其他地方不关闭菜单可以用来滑动多行
			showMask: {
				type: Boolean,
				default: true
			},
		},
		watch: {
			options(newValue, oldValue) {
				this.updateMovesize();
			},
		},
		data() {
			return {
				startPos: {
					pageX: 0,
					pageY: 0
				},
				//限制滑动距离
				moveSize: 0,
				position: {
					pageX: 0,
					pageY: 0
				},
				isShowBtn: false,
				move: false
			};
		},
		mounted() {
			this.updateMovesize();
		},
		methods: {
			swipeDirection(x1, x2, y1, y2) {
				return Math.abs(x1 - x2) >= Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : y1 - y2 > 0 ? 'Up' :
					'Down';
			},
			//阻止事件冒泡
			loop() {},
			updateMovesize() {
				let win = uni.getSystemInfoSync().windowWidth / 750
				if (this.options.length > 0) {
					this.moveSize = 0;
					this.options.forEach(item => {
						this.moveSize += Math.floor(item.width * win);
					});
				}
			},
			onTouchstart(event) {
				event.preventDefault();
				if (this.options.length == 0) return;
				let touches = event.touches
				if (touches && touches.length > 1) return;
				this.move = true;
				touches = touches ? event.touches[0] : {};
				if (!touches || (touches.pageX === undefined && touches.pageY === undefined)) {
					touches = {
						pageX: event.pageX,
						pageY: event.pageY
					};
				}
				const startPos = this.startPos;
				if (touches) {
					for (let i in startPos) {
						if (touches[i]) {
							startPos[i] = touches[i];
						}
					}
				}
			},
			swipper(touches) {
				const start = this.startPos;
				const spacing = {
					pageX: touches.pageX - start.pageX,
					pageY: touches.pageY - start.pageY
				};
				if (this.moveSize < Math.abs(spacing.pageX)) {
					spacing.pageX = -this.moveSize;
				}
				this.position = spacing;
			},
			onTouchmove(event) {
				if (this.options.length == 0 || !this.move) return;
				const start = this.startPos;
				let touches = event.touches ? event.touches[0] : {};
				if (!touches || (touches.pageX === undefined && touches.pageY === undefined)) {
					touches = {
						pageX: event.pageX,
						pageY: event.pageY
					};
				}
				if (touches) {
					const direction = this.swipeDirection(start.pageX, touches.pageX, start.pageY, touches.pageY);
					if (direction === 'Left' && Math.abs(this.position.pageX) !== this.moveSize) {
						this.swipper(touches);
					}
				}
			},
			onTouchend(event) {
				if (this.options.length == 0 || !this.move) return;
				this.move = false;
				const start = this.startPos;
				let touches = event.changedTouches ? event.changedTouches[0] : {};
				if (!touches || (touches.pageX === undefined && touches.pageY === undefined)) {
					touches = {
						pageX: event.pageX,
						pageY: event.pageY
					};
				}
				if (touches) {
					const direction = this.swipeDirection(start.pageX, touches.pageX, start.pageY, touches.pageY);
					const spacing = {
						pageX: touches.pageX - start.pageX,
						pageY: touches.pageY - start.pageY
					};
					if (Math.abs(spacing.pageX) >= 40 && direction === 'Left') {
						spacing.pageX = spacing.pageX < 0 ? -this.moveSize : this.moveSize;
						this.isShowBtn = true;
					} else {
						spacing.pageX = 0;
					}
					if (spacing.pageX == 0) {
						this.isShowBtn = false;
					}
					this.position = spacing;

				}
			},
			handlerButton(index) {
				
				if (this.isClickClose) {
					this.closeSwipe();
				}
				this.$emit('clickItem', {
					index
				});
			},
			closeSwipe() {
				this.position = {
					pageX: 0,
					pageY: 0
				};
				this.isShowBtn = false;
			},
		}
	};
</script>

<style lang="scss" scoped>
	.lSwipeAction {
		
		position: relative;
		overflow: hidden;
		-webkit-tap-highlight-color: rgba(0,0,0,0);
		

		.swipe-action-show {
			position: relative;
			z-index: 998;
		}

		.swipe-item {
			width: 100%;
			box-sizing: border-box;
			transition: transform 0.2s ease;
			font-size: 14px;
			cursor: pointer;

			.swipe-content {
				white-space: nowrap;
				overflow: hidden;
			}

			.swipe-button-right-group {
				position: absolute;
				right: -100%;
				top: 0;
				height: 100%;
				z-index: 1;
				width: 100%;

				.swipe-button-right-item {
					-webkit-tap-highlight-color: rgba(0,0,0,0);
					height: 193rpx;
					border-radius: 10rpx;
					float: left;
					white-space: nowrap;
					box-sizing: border-box;
					display: flex;
					flex-direction: column;
					align-items: center;
					justify-content: center;
					text-align: center;
				}
			
			}
		}

		.swipe-action-mask {
			display: block;
			opacity: 0;
			position: fixed;
			z-index: 997;
			top: 0;
			left: 0;
			width: 100%;
			height: 195rpx;

		}
	}
</style>